import tkinter as tk
from tkinter import ttk, scrolledtext, StringVar, IntVar, BooleanVar
import time
from .server_connection import ServerConnection
from .terminal_execution import TerminalExecution
from .file_upload import FileUpload
from .file_download import FileDownload
from .config_manager import ConfigManager
from .ipc_deploy import IPCDeployer
import logging

logger = logging.getLogger(__name__)


class MainWindow:
    def __init__(self, root):
        self.root = root
        self.root.title("SSH服务器管理工具")
        self.root.geometry("1400x950")
        
        # 尝试设置图标，如果失败则忽略（适用于打包后的情况）
        try:
            self.root.iconbitmap("ssh.ico")
        except:
            try:
                import sys, os
                if getattr(sys, 'frozen', False):
                    icon_path = os.path.join(sys._MEIPASS, "ssh.ico")
                    self.root.iconbitmap(icon_path)
            except:
                pass
        
        self.root.option_add("*Font", "Arial 10")

        # 初始化配置管理器
        self.config = ConfigManager()

        # 初始化各个模块
        self.server_connection = ServerConnection(self)
        self.terminal_execution = TerminalExecution(self)
        self.file_upload = FileUpload(self)
        self.file_download = FileDownload(self)
        self.ipc_deployer = IPCDeployer(self)

        # 变量定义，从配置文件中读取默认值
        self.server_file_path = StringVar(value=self.config.get('sys', 'server_file'))
        self.upload_path = StringVar()
        self.target_dir = StringVar(value=self.config.get('upload', 'default_remote_dir'))
        self.target_dir.trace_add('write', self._on_target_dir_changed)
        self.develop_mode = IntVar(value=self.config.getboolean('sys', 'develop_mode'))
        self.develop_password = StringVar(value=self.config.get('sys', 'develop_password'))
        self.batch_execute = BooleanVar(value=self.config.getboolean('sys', 'batch_execute'))
        
        # 部署选项全选/取消全选按钮的文本变量
        self.deploy_select_all_button_text = StringVar(value="全选")

        # 全选/取消全选按钮的文本变量
        self.select_all_button_text = StringVar(value="全选")

        # 部署相关的复选框变量
        self.deploy_vars = {
            'configure_hostname': BooleanVar(value=self.config.getboolean('deploy', 'configure_hostname')),
            'configure_hosts': BooleanVar(value=self.config.getboolean('deploy', 'configure_hosts')),
            'configure_dns': BooleanVar(value=self.config.getboolean('deploy', 'configure_dns')),
            'sync_time': BooleanVar(value=self.config.getboolean('deploy', 'sync_time')),
            'load_image': BooleanVar(value=self.config.getboolean('deploy', 'load_image')),
            'register_node': BooleanVar(value=self.config.getboolean('deploy', 'register_node'))
        }

        # 修改时间同步和网卡名称变量的初始化方式
        self.sync_time_value = StringVar()
        self.sync_time_value.trace_add('write', self._on_sync_time_changed)
        self.network_interface = StringVar(value=self.config.get('deploy', 'network_interface'))

        # SSH隧道相关变量
        self.enable_ssh_tunnel = BooleanVar(value=self.config.getboolean('ssh_tunnel', 'enable'))
        self.jump_host_server = StringVar(value=self.config.get('ssh_tunnel', 'jump_host'))
        self.jump_host_username = StringVar(value=self.config.get('ssh_tunnel', 'username'))
        self.jump_host_password = StringVar(value=self.config.get('ssh_tunnel', 'password'))

        # 创建主框架
        self.create_main_frame()
        
        # 加载默认设置
        self.load_default_upload_settings()
        self.load_default_download_settings()
        
        # 执行自动功能
        self.perform_auto_actions()

    def _on_sync_time_changed(self, *args):
        """当时间输入框值变化时的回调函数"""
        if hasattr(self, 'time_combo'):
            self.time_combo.set(self.sync_time_value.get())

    def _on_target_dir_changed(self, *args):
        """目标目录变化时的回调函数"""
        new_value = self.target_dir.get()
        logger.info(f"目标目录已更新为: {new_value}")

    def create_main_frame(self):
        # 获取当前系统时间作为默认值
        current_time = time.strftime("%Y-%m-%d %H:%M")

        # 设置 root 使用 grid 布局
        self.root.grid_rowconfigure(0, weight=1)  # top_frame (服务器表格)
        self.root.grid_rowconfigure(1, weight=2)  # mid_frame (终端和命令)
        self.root.grid_rowconfigure(2, weight=1)  # bottom_frame (上传和部署)
        self.root.grid_columnconfigure(0, weight=1)

        # ======================
        # 上部框架
        # ======================
        self.top_frame = ttk.Frame(self.root)
        self.top_frame.grid(row=0, column=0, sticky="nsew")

        # 服务器表格
        self.server_connection.create_server_table()
        self.server_connection.server_table.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        # 按钮框架
        button_frame = ttk.Frame(self.top_frame, padding="10 5 10 5")
        button_frame.pack(fill=tk.X)

        # 服务器信息文件选择
        ttk.Button(button_frame, text="系统配置", command=self.show_config_dialog).pack(side=tk.LEFT, padx=(0, 10))
        ttk.Label(button_frame, text="服务器信息文件:").pack(side=tk.LEFT)
        ttk.Entry(button_frame, textvariable=self.server_file_path, width=40).pack(side=tk.LEFT)
        ttk.Button(button_frame, text="浏览", command=self.browse_server_file).pack(side=tk.LEFT, padx=(10, 10))
        ttk.Button(button_frame, text="加载服务器信息", command=self.load_server_info).pack(side=tk.LEFT, padx=(10, 10))
        ttk.Button(button_frame, textvariable=self.select_all_button_text, command=self.toggle_select_all).pack(side=tk.LEFT, padx=(10, 10))
        ttk.Button(button_frame, text="连接服务器", command=self.connect_selected_servers).pack(side=tk.LEFT, padx=(10, 10))
        ttk.Button(button_frame, text="关闭连接", command=self.disconnect_selected_servers).pack(side=tk.LEFT, padx=(10, 10))
        ttk.Button(button_frame, text="打开华为云", command=self.open_huawei_cloud).pack(side=tk.LEFT, padx=(10, 10))

        # SSH隧道功能, Develop模式, 密码 (都放在第二行)
        ssh_tunnel_row_frame = ttk.Frame(self.top_frame, padding="10 5 10 5")
        ssh_tunnel_row_frame.pack(fill=tk.X)

        ttk.Checkbutton(ssh_tunnel_row_frame, text="启用SSH隧道", variable=self.enable_ssh_tunnel,
                        command=self._on_ssh_tunnel_toggle).pack(side=tk.LEFT, padx=5)
        self.enable_ssh_tunnel.trace_add('write',
                                         lambda *args: self.config.set('ssh_tunnel', 'enable', str(self.enable_ssh_tunnel.get())))
        ttk.Label(ssh_tunnel_row_frame, text="跳板机服务器:").pack(side=tk.LEFT, padx=5)
        self.jump_host_entry = ttk.Entry(ssh_tunnel_row_frame, textvariable=self.jump_host_server, width=20)
        self.jump_host_entry.pack(side=tk.LEFT)
        ttk.Label(ssh_tunnel_row_frame, text="用户:").pack(side=tk.LEFT, padx=5)
        self.jump_host_username_entry = ttk.Entry(ssh_tunnel_row_frame, textvariable=self.jump_host_username, width=15)
        self.jump_host_username_entry.pack(side=tk.LEFT)
        ttk.Label(ssh_tunnel_row_frame, text="密码:").pack(side=tk.LEFT, padx=5)
        self.jump_host_password_entry = ttk.Entry(ssh_tunnel_row_frame, textvariable=self.jump_host_password, show="*", width=15)
        self.jump_host_password_entry.pack(side=tk.LEFT)

        # Develop模式和密码
        ttk.Checkbutton(ssh_tunnel_row_frame, text="Develop模式", variable=self.develop_mode).pack(side=tk.LEFT, padx=(10, 5))
        ttk.Label(ssh_tunnel_row_frame, text="密码:").pack(side=tk.LEFT, padx=(0, 5))
        ttk.Entry(ssh_tunnel_row_frame, textvariable=self.develop_password, show="*", width=15).pack(side=tk.LEFT, padx=(0, 10))

        # 批量执行选项
        ttk.Checkbutton(ssh_tunnel_row_frame, text="批量执行命令", variable=self.batch_execute).pack(side=tk.LEFT, padx=(10, 5))

        self._on_ssh_tunnel_toggle()

        # ======================
        # 中间框架 - 终端和命令输入 - 工控机部署
        # ======================
        self.mid_frame = ttk.Frame(self.root)
        self.mid_frame.grid(row=1, column=0, sticky="nsew")

        # 设置中间框架的列权重
        self.mid_frame.grid_columnconfigure(0, weight=6)  # 左框架占大部分
        self.mid_frame.grid_columnconfigure(1, weight=0)  # 右框架宽度固定
        self.mid_frame.grid_rowconfigure(0, weight=1)

        # 左框架 - 终端和命令输入
        self.left_mid_frame = ttk.Frame(self.mid_frame)
        self.left_mid_frame.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)

        # 右框架 - 工控机部署
        self.right_mid_frame = ttk.Frame(self.mid_frame, width=350)
        self.right_mid_frame.grid(row=0, column=1, sticky="ns", padx=5, pady=5)
        self.right_mid_frame.grid_propagate(False)  # 禁止自动拉伸宽度

        # 创建终端标签页
        self.terminal_execution.create_terminal_tabs()

        # 命令输入框
        cmd_frame = ttk.Frame(self.left_mid_frame, padding="10 5 10 5", height=50)
        cmd_frame.pack(fill=tk.X, side=tk.BOTTOM)
        cmd_frame.pack_propagate(False)

        ttk.Label(cmd_frame, text="命令:").pack(side=tk.LEFT, padx=5)
        self.cmd_entry = ttk.Entry(cmd_frame)
        self.cmd_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
        self.cmd_entry.bind("<Return>", self.execute_command)
        ttk.Button(cmd_frame, text="执行", command=lambda: self.execute_command()).pack(side=tk.RIGHT, padx=5)

        # ======================
        # 右中框架内容：工控机部署配置
        # ======================
        deploy_frame = ttk.LabelFrame(self.right_mid_frame, text="门架工控机部署", padding="10 5 10 5")
        deploy_frame.pack(fill=tk.Y, expand=True, padx=10, pady=5)

        # 部署选项复选框
        deploy_options = [
            ("配置主机名", 'configure_hostname'),
            ("配置hosts文件", 'configure_hosts'),
            ("配置DNS解析", 'configure_dns'),
            ("同步时间", 'sync_time'),
            ("加载镜像", 'load_image'),
            ("节点注册", 'register_node')
        ]

        # 添加时间输入框和网卡名称输入框
        for i, (text, var_name) in enumerate(deploy_options):
            option_frame = ttk.Frame(deploy_frame)
            option_frame.pack(anchor="w", pady=2, fill=tk.X)

            cb = ttk.Checkbutton(
                option_frame,
                text=text,
                variable=self.deploy_vars[var_name],
                command=lambda v=var_name: self.config.set('deploy', v, str(self.deploy_vars[v].get()))
            )
            cb.pack(side=tk.LEFT, padx=(0, 5))

            # 在同步时间选项后添加时间输入框
            if var_name == 'sync_time':
                self.time_combo = ttk.Combobox(
                    option_frame,
                    textvariable=self.sync_time_value,
                    width=20,
                    values=[
                        current_time,
                        time.strftime("%Y-%m-%d 00:00"),
                        time.strftime("%Y-%m-%d 12:00"),
                        time.strftime("%Y-%m-%d 23:59")
                    ]
                )
                self.time_combo.pack(side=tk.LEFT)
                self.time_combo.set(current_time)
                
                def update_time_to_now():
                    now = time.strftime("%Y-%m-%d %H:%M")
                    self.time_combo.set(now)
                ttk.Button(option_frame, text="获取当前日期和时间", command=update_time_to_now).pack(side=tk.LEFT, padx=5)

                # 初始状态根据复选框设置
                self.time_combo.config(state=tk.NORMAL if self.deploy_vars['sync_time'].get() else tk.DISABLED)
                # 绑定复选框状态变化事件
                self.deploy_vars['sync_time'].trace_add('write', self._on_sync_time_toggle)

            # 在加载镜像选项后添加网卡名称输入框
            elif var_name == 'load_image':
                ttk.Label(option_frame, text="网卡:").pack(side=tk.LEFT)
                ttk.Entry(option_frame, textvariable=self.network_interface, width=15).pack(side=tk.LEFT)

        # 初始化一次控件状态
        self.update_time_combo_state()

        # 创建按钮框架，将全选和部署按钮放在同一行
        deploy_button_frame = ttk.Frame(deploy_frame)
        deploy_button_frame.pack(fill=tk.X, pady=5)
        
        # 添加部署选项全选/取消全选按钮
        ttk.Button(deploy_button_frame, textvariable=self.deploy_select_all_button_text, command=self.toggle_deploy_select_all).pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 5))
        
        # 添加部署按钮
        ttk.Button(deploy_button_frame, text="执行部署", command=self.batch_deploy_ipc).pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(5, 0))
        
        # 初始化部署全选按钮文本
        self._update_deploy_select_all_button_text()

        # ======================
        # 下部框架（左右分栏）
        # ======================
        self.bottom_frame = ttk.Frame(self.root)
        self.bottom_frame.grid(row=2, column=0, sticky="nsew")

        self.left_bottom_frame = ttk.Frame(self.bottom_frame, padding="5")
        self.right_bottom_frame = ttk.Frame(self.bottom_frame, padding="10")

        self.left_bottom_frame.grid(row=0, column=0, sticky="nsew")
        self.right_bottom_frame.grid(row=0, column=1, sticky="nsew")

        # 设置比例 2:1
        self.bottom_frame.grid_columnconfigure(0, weight=1)
        self.bottom_frame.grid_columnconfigure(1, weight=1)
        self.bottom_frame.grid_rowconfigure(0, weight=1)

        # 创建上传下载区域框架
        self.file_upload.create_upload_frame(self.left_bottom_frame)
        self.file_download.create_download_frame(self.right_bottom_frame)

    def toggle_deploy_select_all(self):
        """部署选项全选/取消全选功能"""
        all_selected = True

        # 检查是否所有部署选项都已选中
        for var_name, var in self.deploy_vars.items():
            if not var.get():
                all_selected = False
                break

        # 根据状态选择或取消全选所有部署选项
        for var_name, var in self.deploy_vars.items():
            var.set(not all_selected)

        # 更新按钮文本
        self._update_deploy_select_all_button_text()

    def _update_deploy_select_all_button_text(self):
        """根据部署选项选择状态更新全选/取消全选按钮的文本"""
        all_selected = True
        has_any_selection = False
        for var_name, var in self.deploy_vars.items():
            if not var.get():
                all_selected = False
            else:
                has_any_selection = True

        if all_selected and has_any_selection:
            self.deploy_select_all_button_text.set("取消全选")
        else:
            self.deploy_select_all_button_text.set("全选")

    def show_config_dialog(self):
        """显示系统配置对话框"""
        from .config_dialog import ConfigDialog
        ConfigDialog(self)

    def browse_server_file(self):
        """浏览服务器文件"""
        from tkinter import filedialog
        file_path = filedialog.askopenfilename(filetypes=[("Excel文件", "*.xlsx"), ("文本文件", "*.txt"), ("所有文件", "*.*")])
        if file_path:
            self.server_file_path.set(file_path)

    def load_server_info(self):
        """加载服务器信息"""
        self.server_connection.load_server_info()

    def toggle_select_all(self):
        """切换全选状态"""
        self.server_connection.toggle_select_all()

    def connect_selected_servers(self):
        """连接选中的服务器"""
        self.server_connection.connect_selected_servers()

    def disconnect_selected_servers(self):
        """断开选中的服务器连接"""
        self.server_connection.disconnect_selected_servers()

    def execute_command(self, event=None):
        """执行命令"""
        self.terminal_execution.execute_command(event)

    def batch_deploy_ipc(self):
        """批量部署工控机"""
        self.ipc_deployer.batch_deploy_ipc()

    def open_huawei_cloud(self):
        """打开华为云控制台"""
        self.ipc_deployer.open_huawei_cloud()

    def _on_ssh_tunnel_toggle(self, *args):
        """SSH隧道复选框状态变化时的回调"""
        state = tk.NORMAL if self.enable_ssh_tunnel.get() else tk.DISABLED
        self.jump_host_entry.config(state=state)
        self.jump_host_username_entry.config(state=state)
        self.jump_host_password_entry.config(state=state)
        # 同时也保存到配置文件
        self.config.set('ssh_tunnel', 'enable', str(self.enable_ssh_tunnel.get()))

    def _on_sync_time_toggle(self, *args):
        """处理同步时间复选框状态变化"""
        if self.deploy_vars['sync_time'].get():
            self.time_combo.config(state=tk.NORMAL)
        else:
            self.time_combo.config(state=tk.DISABLED)

    def update_time_combo_state(self):
        """更新时间组合框状态"""
        if self.deploy_vars['sync_time'].get():
            self.time_combo.config(state='readonly')
        else:
            self.time_combo.config(state='disabled')

    def load_default_upload_settings(self):
        """加载默认上传设置"""
        default_files = self.config.get('upload', 'default_files', default='')
        if default_files:
            self.file_upload.upload_text.delete(1.0, tk.END)
            self.file_upload.upload_text.insert(tk.END, default_files)
        
        default_remote_dir = self.config.get('upload', 'default_remote_dir', default='/tmp')
        self.target_dir.set(default_remote_dir)

    def load_default_download_settings(self):
        """加载默认下载设置"""
        default_files = self.config.get('download', 'default_files', default='')
        if default_files:
            self.file_download.remote_path_text.delete(1.0, tk.END)
            self.file_download.remote_path_text.insert(tk.END, default_files)
        
        default_save_path = self.config.get('download', 'default_save_path', default='')
        if default_save_path:
            self.file_download.local_path_entry.delete(0, tk.END)
            self.file_download.local_path_entry.insert(0, default_save_path)

    def show_message(self, message):
        """显示消息"""
        self.terminal_execution.show_message(message)
    
    def perform_auto_actions(self):
        """执行自动功能"""
        logger.info("开始执行自动功能...")
        
        # 检查是否启用自动加载服务器
        if self.config.getboolean('sys', 'auto_load_servers', default=False):
            logger.info("自动加载服务器功能已启用")
            
            # 检查服务器文件路径是否存在
            server_file = self.server_file_path.get()
            if server_file and server_file.strip():
                logger.info(f"自动加载服务器信息文件: {server_file}")
                # 延迟执行，确保界面完全加载
                self.root.after(1000, self._auto_load_servers)
            else:
                logger.warning("自动加载服务器功能已启用，但服务器文件路径为空")
        else:
            logger.info("自动加载服务器功能未启用")
    
    def _auto_load_servers(self):
        """自动加载服务器信息"""
        try:
            logger.info("执行自动加载服务器信息")
            self.server_connection.load_server_info()
            
            # 检查是否启用自动全选服务器
            if self.config.getboolean('sys', 'auto_select_all_servers', default=False):
                logger.info("自动全选服务器功能已启用")
                # 延迟执行全选操作
                self.root.after(500, self._auto_select_all_servers)
            else:
                logger.info("自动全选服务器功能未启用")
                
        except Exception as e:
            logger.error(f"自动加载服务器信息失败: {e}")
    
    def _auto_select_all_servers(self):
        """自动全选服务器"""
        try:
            logger.info("执行自动全选服务器")
            self.server_connection.toggle_select_all()
            
            # 检查是否启用自动连接服务器
            if self.config.getboolean('sys', 'auto_connect_servers', default=False):
                logger.info("自动连接服务器功能已启用")
                # 延迟执行连接操作
                self.root.after(500, self._auto_connect_servers)
            else:
                logger.info("自动连接服务器功能未启用")
                
        except Exception as e:
            logger.error(f"自动全选服务器失败: {e}")
    
    def _auto_connect_servers(self):
        """自动连接服务器"""
        try:
            logger.info("执行自动连接服务器")
            self.server_connection.connect_selected_servers()
            logger.info("自动连接服务器操作已启动")
        except Exception as e:
            logger.error(f"自动连接服务器失败: {e}") 